package com.cyou.gamehistory.service;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.cyou.annals.bean.News;
import com.cyou.annals.util.AnnalsClient;
import com.cyou.framework.cache.memcached.SpyMemcachedClient;
import com.cyou.framework.pagination.proxy.PaginationSupport;
import com.cyou.framework.util.StringUtility;
import com.cyou.gamehistory.entity.Game;
import com.cyou.gamehistory.entity.GameHistory;
import com.cyou.gamehistory.entity.UserInfo;
import com.cyou.gamehistory.entity.vo.GameStat;
import com.cyou.gamehistory.repository.GameDao;
import com.cyou.gamehistory.repository.GameHistoryDao;
import com.cyou.gamehistory.repository.UserInfoDao;
import com.cyou.gamehistory.util.ApplicationConfig;
import com.cyou.gamehistory.util.HtmlToImage;
import com.cyou.gamehistory.util.MemcachedObjectType;

import freemarker.template.Configuration;
import freemarker.template.Template;

/**
 * 编年史
 * 
 * @author wangzhang
 */
@Component
@Transactional(readOnly = true)
public class GameHistoryService {

	private static final Logger logger = LoggerFactory.getLogger(GameHistoryService.class);

	@Autowired
	private GameHistoryDao gameHistoryDao;
	@Autowired
	private GameDao gameInfoDao;
	@Autowired
	private UserInfoDao userInfoDao;
	@Autowired
	private SpyMemcachedClient spyMemcachedClient;
	
	public static final String APP_KEY = "gamehistory";
	public static final String APP_NAME = "game history";
	public static final String NEWS_KEY = "NEWS_MEMCACHE_KEY";
	
	
	@Transactional
	public void saveBatch(Integer userId,String[] gameCode,String[] cost,String[] orderNum,String[] playBeginTime,String[] story){
		this.deleteHistory(userId);
		List<GameHistory> list = new ArrayList<GameHistory>();
		Integer storyCount=0;
		for(int i=0;i<gameCode.length;i++){
			GameHistory gameHistory=new GameHistory();
			if(cost!=null&&cost.length>0&&StringUtility.isNotBlank(cost[i])){
				gameHistory.setCost(Double.valueOf(cost[i]));
			}else{
				gameHistory.setCost(0d);
			}
			gameHistory.setCreateTime(new Date());
			gameHistory.setGameCode(gameCode[i]);
			gameHistory.setOrderNum(Integer.valueOf(orderNum[i]));
			gameHistory.setPlayBeginTime(playBeginTime[i]);
			String storyStr="";
			if(story!=null&&story.length>0&&StringUtility.isNotBlank(story[i])){
				storyCount++;
				storyStr=story[i].trim();
			}
			gameHistory.setStory(storyStr);
			gameHistory.setUserId(userId);
			list.add(gameHistory);
		}
		this.saveBatch(list);
	}
	@Transactional
	private void saveBatch(List<GameHistory> list) {
		// 保存之前，将appinfo清空
		String key = MemcachedObjectType.AppInfo.getPrefix() + APP_KEY;
		spyMemcachedClient.delete(key);
		gameHistoryDao.saveBatch(list);
		logger.debug("保存编年史成功");
	}
	
	/**
	 * 删除某个用户的游戏编年史
	 * @param userId
	 */
	@Transactional
	private void deleteHistory(Integer userId) {
		gameHistoryDao.deleteByUserId(userId);
	}
	/**
	 * 批量删除
	 * @param userId
	 */
	@Transactional
	public void deleteHistory(String id[]) {
		gameHistoryDao.deleteBatch(id);
	}
	/**
	 * 获取编年史页首次十条数据
	 * @param id
	 * @return
	 */
	public List<GameHistory> getGameHistoryList(Integer id) {
		List<GameHistory> gameHistoryList = gameHistoryDao.getGameHistoryList(id);
		for (GameHistory gh : gameHistoryList) {
			Game gameInfo = gameInfoDao.getGameInfoByCode(gh.getGameCode());
			gh.setGameInfo(gameInfo);
		}
		return gameHistoryList;
	}
	/**
	 * 获取编年史页个人图片 模板页的  前九条数据
	 * @param id
	 * @return
	 */
	public List<GameHistory> getGameHistoryListForImage(Integer id) {
		List<GameHistory> gameHistoryList = gameHistoryDao.getGameHistoryListForImage(id);
		for (GameHistory gh : gameHistoryList) {
			Game gameInfo = gameInfoDao.getGameInfoByCode(gh.getGameCode());
			gh.setGameInfo(gameInfo);
		}
		return gameHistoryList;
	}
	/**
	 * 获取用户编年史中的年份
	 * @param userId
	 * @return
	 */
	public List<String> getHistoryYears(Integer userId) {
		return gameHistoryDao.getHistoryYear(userId);
	}

	/**
	 * 获取游戏编年史map  用户前台jstl  显示        
	 * 
	 * @param gameHistoryList 游戏编年史列表
	 * @param listYear    编年史中游戏的playbegintime
	 * @return
	 */
	public Map<String, List<GameHistory>> getGameHistoryMap(List<GameHistory> gameHistoryList, List<String> listYear) {
		Map<String, List<GameHistory>> map = new LinkedHashMap<String, List<GameHistory>>();
		for (String year : listYear) {
			List<GameHistory> list = new ArrayList<GameHistory>();
			for (GameHistory gameHistory : gameHistoryList) {
				if (gameHistory.getPlayBeginTime().equals(year)) {
					list.add(gameHistory);
				}
			}
			map.put(year, list);
		}
		return map;

	}
	/**
	 * 通过gameHistoryList 获取一个map    map中value  存放15条数据  用于我的编年史页面 上方显示
	 * @param gameHistoryList
	 * @return
	 */
	public Map<String, List<GameHistory>> getMapList(List<GameHistory> gameHistoryList) {
		Map<String, List<GameHistory>> map = new LinkedHashMap<String, List<GameHistory>>();
		List<GameHistory> list = new ArrayList<GameHistory>();
		String key="gameHistoryMapKey";
		for (Integer i = 0; i < gameHistoryList.size(); i++) {
			list.add(gameHistoryList.get(i));
			if ((i+1) % 15 == 0 && (i+1) !=gameHistoryList.size()) {
				list=new ArrayList<GameHistory>();
				key=key+String.valueOf(i);
			}
			map.put(key, list);
		}
		return map;
	}
	/**
	 * 获取某个人的所有编年史     --按照play_begin_time 排序
	 * @param userId
	 * @return
	 */
	public List<GameHistory> getAllGameHistoryList(Integer userId) {
		List<GameHistory> gameHistoryList = gameHistoryDao.getAllGameHistoryList(userId);
		for (GameHistory gh : gameHistoryList) {
			Game gameInfo = gameInfoDao.getGameInfoByCode(gh.getGameCode());
			gh.setGameInfo(gameInfo);
		}
		return gameHistoryList;
	}
	/**
	 * 获取某个人的所有编年史     --按照order_num 排序
	 * @param userId
	 * @return
	 */
	public List<GameHistory> getAllGameHistoryListByOrderNum(Integer userId) {
		List<GameHistory> gameHistoryList = gameHistoryDao.getAllGameHistoryListByOrderNum(userId);
		for (GameHistory gh : gameHistoryList) {
			Game gameInfo = gameInfoDao.getGameInfoByCode(gh.getGameCode());
			gh.setGameInfo(gameInfo);
		}
		return gameHistoryList;
	}
	/**
	 * 获取编年史分页列表  (后台用)
	 * @param orderFlag 升序或者降序标记--asc or desc
	 * @param createTimeBegin 
	 * @param createTimeEnd
	 * @param story
	 * @param pageSize
	 * @param pageNo
	 * @return
	 */
	public PaginationSupport<GameHistory> getAllGameHistoryList(String orderFlag,String createTimeBegin,String createTimeEnd,String story,Integer pageSize, Integer pageNo){
		Map<String, Object> map = new HashMap<String, Object>();
		
		PaginationSupport<GameHistory> pageinationSupport = new PaginationSupport<GameHistory>();
		pageinationSupport.setCurrentPage(pageNo);
		pageinationSupport.setPageSize(pageSize);

		map.put("page", pageinationSupport);
		if(StringUtility.isNotBlank(createTimeBegin)){
			createTimeBegin=createTimeBegin+" 00:00:00";
		}
		if(StringUtility.isNotBlank(createTimeEnd)){
			createTimeEnd=createTimeEnd+" 23:59:59";
		}
		map.put("createTimeBegin",createTimeBegin );
		map.put("createTimeEnd", createTimeEnd);
		map.put("story", story);
		map.put("orderFlag", orderFlag);
		
		PaginationSupport<GameHistory> gameHistoryList=gameHistoryDao.findAllGameHistoryList(map);
		List<GameHistory> list=gameHistoryList.getDatas();
		for(GameHistory gameHistory:list){
			UserInfo userInfo=userInfoDao.getByUserId(gameHistory.getUserId());
			gameHistory.setUserInfo(userInfo);
		}
		return gameHistoryList;
		
	}
	/**
	 * 生成用户编年史图片
	 */
	public void createSpaceImage(Configuration config, UserInfo userinfo, Integer userCount,String originalImageName) throws Throwable {
		logger.info("createSpaceImage begin");
		
		String htmlDirectory = ApplicationConfig.getValue("annalsImage.htmlDirectory");
		String imageDirectory = ApplicationConfig.getValue("annalsImage.imageDirectory");
		String staticPath = ApplicationConfig.getValue("staticPath");

		String templatePath = "/WEB-INF/views/front/template/gameHistoryImage.ftl";
		String htmlFileName = htmlDirectory + "/" + String.valueOf(userinfo.getUserId())+".html";
		String imageFileName = imageDirectory + "/" + userinfo.getGameHistoryImage();
		
		//删除原来的图片文件
		if(StringUtility.isNotBlank(originalImageName)){
			String oImageName = imageDirectory + "/" +originalImageName;
			File originalImageFile=new File(oImageName);
			if(originalImageFile.exists()){
				originalImageFile.delete();
			}
		}
		//创建文件
		File htmlFile = new File(htmlFileName);
		if (!htmlFile.getParentFile().exists()) {
			htmlFile.getParentFile().mkdirs();
		}
		if (!htmlFile.exists()) {
			htmlFile.createNewFile();
		}
		File imageFile = new File(imageFileName);
		if (!imageFile.getParentFile().exists()) {
			imageFile.getParentFile().mkdirs();
		}
	
		//freemarker页面数字格式化     例如 将2,000格式化成2000
		config.setNumberFormat("#");

		// 根据模板和数据生成静态HTML
		Template template = config.getTemplate(templatePath, "UTF-8");
		Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile), "UTF-8"));
		Map<String,Object> data = new HashMap<String,Object>();

		List<GameHistory> ghlist = this.getGameHistoryListForImage(userinfo.getUserId());
		
		Integer rank=userInfoDao.rank(userinfo.getUserId());
		data.put("rank",rank);
		data.put("gameHistoryList", ghlist);
		data.put("staticPath", staticPath);
		data.put("userCount", userCount);
		data.put("userinfo", userinfo);
		template.process(data, out);
		
		// 根据静态HTMl生成图片
		HtmlToImage.html2Image(htmlFileName, imageFileName, 600, 400);
		
		logger.info("createSpaceImage end");
	}
	
	/**
	 * 获取随机的一条新闻记录
	 * @return
	 */
	public News getRandomNews(){
		List<News> newsList = getNewsList();
		if (null != newsList && newsList.size() > 0) {
			Random rand = new Random();
			return newsList.get(rand.nextInt(newsList.size()));
		}
		return null;
	}
	
	/**
	 * 调用新闻接口获取新闻列表
	 * @return
	 */
	public List<News> getNewsList(){
		List<News> listNews=spyMemcachedClient.get(NEWS_KEY);
		if(listNews==null){
			listNews=AnnalsClient.getNews();
			if(listNews!=null&&listNews.size()>0){
				spyMemcachedClient.set(NEWS_KEY, 60*60, listNews);//缓存1小时
			}
		}
		return listNews;
	}
	
	/**
	 * 获取游戏使用次数前十的排名   用于后台统计
	 * @return
	 */
	public List<GameStat> getTopGames(){
		return gameHistoryDao.getTopGames();
	}
	/**
	 * 获取生成游戏 年份 前十的排名   用于后台统计
	 * @return
	 */
	public List<GameHistory> getTopYears(){
		return gameHistoryDao.getTopYears();
	}
	public Integer getTotal(){
		return gameHistoryDao.getTotal();
	}
	
	
}
